const TXMap = {
  map: undefined, // 地图对象
  overlays: [], // 所有覆盖物
  un: [], // 原始数据
  listener: undefined, // idle事件监听

  // 异步加载获取api
  getApi(funName) {
    let script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = `https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&callback=${funName}`
    document.body.appendChild(script)
  },
  drawOverlay(options) {
    let _this = this
    this.sourceData = options.data || []
    // 绘制覆盖物之前，清理之前绘制的覆盖物
    this.clearOverlays()
    // 如果 initMap 方法已经实现，那么我们可以直接调用，否则需要进行定义
    if (window.initMap === undefined) {
      let ClusterBubbleClick
      // 如果地图对象还不存在，则需要初始化，避免多次初始化地图对象
      window.initMap = function() {
        if (_this.map === undefined) {
          // 地图对象为undefined时, 需要进行地图的绘制
          var drawContainer = document.getElementById(options.containerId)

          var center = new TMap.LatLng(39.953416, 116.380945)

          _this.map = new TMap.Map(options.containerId, {
            zoom: 4,
            center: center,
            baseMap: {
              //底图设置（参数为：VectorBaseMap对象）
              type: 'vector' //类型：失量底图
              // features: ['base', 'building2d']
              //仅渲染：道路及底面(base) + 2d建筑物(building2d)，以达到隐藏文字的效果
            }
          })
          if (_this.map !== undefined) {
            typeof options.drawed == 'function' && options.drawed()
          }
          // 创建点聚合
          var markerCluster = new TMap.MarkerCluster({
            id: 'cluster',
            map: _this.map,
            enableDefaultStyle: false, // 关闭默认样式
            minimumClusterSize: 3,
            geometries: [
              {
                // 点数组
                position: new TMap.LatLng(39.953416, 116.480945)
              },
              {
                position: new TMap.LatLng(39.984104, 116.407503)
              },
              {
                position: new TMap.LatLng(39.908802, 116.497502)
              },
              {
                position: new TMap.LatLng(40.040417, 116.373514)
              },
              {
                position: new TMap.LatLng(39.953416, 116.380945)
              },
              {
                position: new TMap.LatLng(39.984104, 116.307503)
              },
              {
                position: new TMap.LatLng(39.908802, 116.397502)
              },
              {
                position: new TMap.LatLng(40.040417, 116.273514)
              }
            ],
            zoomOnClick: true,
            gridSize: 60,
            averageCenter: true
          })

          var clusterBubbleList = []
          var markerGeometries = []
          var marker = null

          // 监听聚合簇变化
          markerCluster.on('cluster_changed', function(e) {
            // 销毁旧聚合簇生成的覆盖物
            if (clusterBubbleList.length) {
              clusterBubbleList.forEach(function(item) {
                item.destroy()
              })
              clusterBubbleList = []
            }
            markerGeometries = []

            // 根据新的聚合簇数组生成新的覆盖物和点标记图层
            var clusters = markerCluster.getClusters()
            clusters.forEach(function(item) {
              if (item.geometries.length > 1) {
                let clusterBubble = new ClusterBubble({
                  map: _this.map,
                  position: item.center,
                  content: item.geometries.length
                })
                clusterBubble.on('click', () => {
                  _this.map.fitBounds(item.bounds)
                })
                clusterBubbleList.push(clusterBubble)
              } else {
                markerGeometries.push({
                  position: item.center
                })
              }
            })

            if (marker) {
              // 已创建过点标记图层，直接更新数据
              marker.setGeometries(markerGeometries)
            } else {
              // 创建点标记图层
              marker = new TMap.MultiMarker({
                map: _this.map,
                styles: {
                  default: new TMap.MarkerStyle({
                    width: 34,
                    height: 42,
                    anchor: {
                      x: 17,
                      y: 21
                    },
                    src:
                      'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker_blue.png'
                  })
                },
                geometries: markerGeometries
              })
            }
          })
        }
        // 以下代码为基于DOMOverlay实现聚合点气泡
        function ClusterBubble(options) {
          TMap.DOMOverlay.call(this, options)
        }

        ClusterBubble.prototype = new TMap.DOMOverlay()

        ClusterBubble.prototype.onInit = function(options) {
          this.content = options.content
          this.position = options.position
          console.log(options)
        }

        // 销毁时需要删除监听器
        ClusterBubble.prototype.onDestroy = function() {
          this.dom.removeEventListener('click', this.onClick)
          this.removeAllListeners()
        }

        ClusterBubble.prototype.onClick = function() {
          this.emit('click')
        }

        // 创建气泡DOM元素
        ClusterBubble.prototype.createDOM = function() {
          let dom = document.createElement('div')
          dom.classList.add('clusterBubble')
          let html = ''

          let num =
            this.content > 10000
              ? (this.content / 10000) * 1 + '万'
              : this.content
          html = '<div><p>北京 </p><p>' + null + '</p></div>'
          dom.innerHTML = html
          dom.style.cssText = [
            'width: ' + (40 + parseInt(this.content) * 2) + 'px;',
            'height: ' + (40 + parseInt(this.content) * 2) + 'px;',
            'line-height: ' + (40 + parseInt(this.content) * 2) + 'px;'
          ].join(' ')

          // 监听点击事件，实现zoomOnClick
          this.onClick = this.onClick.bind(this)
          dom.addEventListener('click', this.onClick)
          return dom
        }

        ClusterBubble.prototype.updateDOM = function() {
          if (!this.map) {
            return
          }
          // 经纬度坐标转容器像素坐标
          let pixel = this.map.projectToContainer(this.position)

          // 使文本框中心点对齐经纬度坐标点
          let left = pixel.getX() - this.dom.clientWidth / 2 + 'px'
          let top = pixel.getY() - this.dom.clientHeight / 2 + 'px'
          this.dom.style.transform = `translate(${left}, ${top})`

          this.emit('dom_updated')
        }
        window.ClusterBubble = ClusterBubble
      }
      // 地图 api 如果没有引入则调用 getApi 方法，否则直接调用 initMap ()
      window.TMap === undefined ? this.getApi('initMap') : window.initMap()
    } else {
      window.initMap()
    }
  },
  // 清除自定义覆盖物
  clearOverlays() {
    let overlay
    while ((overlay = this.overlays.pop())) {
      overlay.onclick = null // 移除点击事件
      overlay.parentNode.removeChild(overlay) // 移除 dom 元素
    }
  },
  // 在 Vue 组件的 beforeDestroy 调用，重置地图，移除时间为监听，避免内存泄漏
  clearMap() {
    this.map = undefined
    if (this.listener) {
      window.qq.maps.event.removeListener(this.listener)
    }
  }
}

export default TXMap
